<template>
    <div class="board" @click="blur" @touchstart="blur">
        <div class="canvas" @mousedown="drawDown" @touchstart="drawDown" @mouseup="drawUp" @touchend="drawUp" @mousemove="drawMove" @touchmove="drawMove">
            <div class="answer" v-if="!drawing && board.prev">答案: {{ board.prev }}</div>
            <svg width="100%" height="100%" viewBox="0 0 1000 1000">
                <path v-for="line in canvas.lines" :d="line.points | path" :class="[ line.color, line.size ]"></path>
                <path :d="(hold || canvas.hold) | path" v-if="hold || canvas.hold" :class="[ board.config.color, board.config.size ]"></path>
            </svg>
        </div>
        <div class="palette scrollable" v-if="drawer && (drawing || !board.prev)">
            <a class="btn pigments" :class="[ board.config.color ]" @click="expand = expand === 'pigment' ? false : 'pigment'" @touchstart="expand = expand === 'pigment' ? false : 'pigment'"><i class="fa fa-2x fa-fw fa-tint"></i></a>
            <transition-group name="fade" tag="div" class="expand">
                <a v-for="color in colors" v-if="expand === 'pigment'" :key="color" @click="setColor(color)" @touchstart="setColor(color)" class="pigment" :class="[ color, color === board.config.color ? 'active' : '' ]"></a>
            </transition-group>
            <a class="btn brushes" @click="expand = expand === 'brush' ? false : 'brush'" @touchstart="expand = expand === 'brush' ? false : 'brush'"><div class="size" :class="[ board.config.size ]"></div><i class="fa fa-2x fa-fw fa-paint-brush"></i></a>
            <transition-group name="fade" tag="div" class="expand">
                <a v-for="brush in brushes" v-if="expand === 'brush'" :key="brush" @click="setSize(brush)" @touchstart="setSize(brush)" class="brush" :class="[ brush, brush === board.config.size ? 'active' : '' ]"></a>
            </transition-group>
            <a class="btn" @click="undo" @touchstart="undo"><i class="fa fa-2x fa-fw fa-undo"></i><span>撤销</span></a>
            <a class="btn" @click="empty" @touchstart="empty"><i class="fa fa-2x fa-fw fa-eraser"></i><span>清空</span></a>
            <a class="info"><i class="fa fa-lg fa-fw fa-thumbs-o-up"></i><span>{{ board.count.good }}</span></a>
            <a class="info"><i class="fa fa-lg fa-fw fa-thumbs-down"></i><span>{{ board.count.bad }}</span></a>
        </div>
        <div class="evaluate" v-else="">
            <a class="btn" @click="good" @touchstart="good" :class="{ gray: !drawing && !board.prev || role.comment }"><i class="fa fa-fw fa-thumbs-o-up fa-2x"></i><span>{{ board.count.good }}</span></a>
            <a class="btn" @click="bad" @touchstart="bad" :class="{ gray: !drawing && !board.prev || role.comment }"><i class="fa fa-fw fa-thumbs-down fa-2x"></i><span>{{ board.count.bad }}</span></a>
        </div>
        <div class="complex">
            <transition-group name="role" tag="div" class="roles scrollable">
                <div class="role" v-for="role in queue" :key="role.player.id"><div v-if="role.player.id === player.id" class="self">自己</div><div class="name">{{ role.player.name }}</div><div class="score">{{ board.scores[role.group] }}</div></div>
            </transition-group>
            <div class="info">
                <div class="time">{{ time }}</div>
                <div class="question">{{ board.status === 'ending' ? '结束中...' : board.round >= 3 ? `加时赛${ board.round - 2 }-${ index + 1 }` : `第${ board.round + 1 }-${ index + 1 }局` }} {{ board.status === 'ending' ? '' : question }}</div>
            </div>
            <div id="messages" class="messages scrollable">
                <div class="message" v-for="message in game.messages" v-if="message.role.name !== 'system' || ((!message.role.id || message.role.id === player.id) && (!message.role.not || message.role.not !== player.id))">
                    <div class="system" v-if="message.role.name === 'system'">{{ message.message }}</div>
                    <template v-else=""><div class="role">{{ message.role.player.name }}</div><div class="text">{{ message.message }}</div></template>
                </div>
            </div>
            <transition-group name="message" id="marquee" tag="div" class="marquee">
                <div v-for="(message, index) in game.messages" :key="message" class="message" :class="[ 'line' + (index % lines) ]" v-if="message.role.name !== 'system' || ((!message.role.id || message.role.id === player.id) && (!message.role.not || message.role.not !== player.id))">
                    <div class="system" v-if="message.role.name === 'system'">{{ message.message }}</div>
                    <template v-else=""><div class="role">{{ message.role.player.name }}</div><div class="text">{{ message.message }}</div></template>
                </div>
            </transition-group>
            <div class="send">
                <input ref="input" type="text" v-model="message" :placeholder="drawing ? drawer ? '输入聊天信息' : '输入答案' : '输入聊天信息'" maxlength="30" @keypress.enter="answer" @click="focus" @touchstart="focus">
                <a class="btn" @click="answer" @touchstart="answer">确定</a>
            </div>
        </div>
    </div>
</template>
<style lang="less">
    @import './index';

    .game {
        path {
            fill: transparent;
            &.red { stroke: red; }
            &.blue { stroke: blue; }
            &.yellow { stroke: yellow; }
            &.green { stroke: green; }
            &.white { stroke: white; }
            &.black { stroke: black; }
            &.gray { stroke: gray; }
            &.small { stroke-width: 2px; }
            &.medium { stroke-width: 4px; }
            &.normal { stroke-width: 6px; }
            &.big { stroke-width: 8px; }
            &.large { stroke-width: 10px; }
        }

        .board {
            .full;
            .flex;
            > .canvas {
                width: 100vmin;
                height: 100vmin;
                .min-width;
                .min-height;
                .flex-none;
                .flex-center;
                > .answer {
                    position: absolute;
                    height: 2.5em;
                    width: 100vmin;
                    font-size: 2em;
                    color: white;
                    background: fade(orangered, 30);
                    .flex-center;
                }
            }
            > .palette {
                background-color: lightgray;
                border: 1px solid darkgrey;
                .flex;
                .flex-none;
                > * {
                    .flex-none;
                    .flex-column;
                    .flex-center;
                }
                .pigments {
                    text-shadow: 0 0 1px black;
                    &.red { color: red; }
                    &.blue { color: blue; }
                    &.yellow { color: yellow; }
                    &.green { color: green; }
                    &.white { color: white; }
                    &.black { color: black; }
                    &.gray { color: gray; }
                }
                .pigment {
                    width: 2.5em;
                    height: 2.5em;
                    margin: 0.5em;
                    border-radius: 50%;
                    border: 1px solid black;
                    &.active { border: 5px solid darkgray; }
                    &.red { background-color: red; }
                    &.blue { background-color: blue; }
                    &.yellow { background-color: yellow; }
                    &.green { background-color: green; }
                    &.white { background-color: white; }
                    &.black { background-color: black; }
                    &.gray { background-color: gray; }
                }
                .brushes {
                    position: relative;
                    > .size {
                        position: absolute;
                        background-color: black;
                        border-radius: 50%;
                        top: 1.5em;
                        left: 0.8em;
                        &.small { width: 2px; height: 2px; }
                        &.medium { width: 4px; height: 4px; }
                        &.normal { width: 6px; height: 6px; }
                        &.big { width: 8px; height: 8px; }
                        &.large { width: 10px; height: 10px; }
                    }
                }
                .brush {
                    width: 2.5em;
                    height: 2.5em;
                    margin: 0.5em;
                    border-radius: 50%;
                    border: 1px solid black;
                    .flex-center;
                    &.active { border: 5px solid black; }
                    &:before {
                        content: " ";
                        background-color: black;
                        border-radius: 50%;
                    }
                    &.small:before { width: 2px; height: 2px; }
                    &.medium:before { width: 4px; height: 4px; }
                    &.normal:before { width: 6px; height: 6px; }
                    &.big:before { width: 8px; height: 8px; }
                    &.large:before { width: 10px; height: 10px; }
                }
            }
            > .evaluate {
                background-color: lightgray;
                border: 1px solid darkgrey;
                .flex;
                .flex-none;
                > * {
                    .flex-none;
                    .flex-column;
                    .flex-center;
                    &.gray {
                        > i {
                            color: gray;
                        }
                    }
                }
            }
            > .complex {
                overflow: hidden;
                .flex-1;
                .flex-column;
                > .info {
                    height: 3.25em;
                    color: white;
                    background-color: darkred;
                    .flex-row;
                    > .time {
                        font-size: 1.25em;
                        font-weight: bold;
                        width: 3em;
                        border-right: 1px solid white;
                        .flex-center;
                    }
                    > .question {
                        flex: 1;
                        .flex-center;
                    }
                }
                > .roles {
                    height: 3.25em;
                    .flex-row;
                    .flex-align(flex-start, center);
                    > .role {
                        margin-left: 0.5em;
                        word-break: keep-all;
                        white-space: nowrap;
                        .flex-row;
                        .flex-align(flex-start, center);
                        &:first-child {
                            font-size: 1.25em;
                            font-weight: bold;
                        }
                        > *:first-child {
                            border-top-left-radius: 0.25em;
                            border-bottom-left-radius: 0.25em;
                        }
                        > .self {
                            padding: 0.25em 0.5em;
                            background-color: lightgreen;
                        }
                        > .name {
                            padding: 0.25em 0.5em;
                            background-color: skyblue;
                        }
                        > .score {
                            padding: 0.25em 0.5em;
                            border-top-right-radius: 0.25em;
                            border-bottom-right-radius: 0.25em;
                            background-color: pink;
                        }
                    }
                }
                > .messages {
                    .flex-1;
                    .flex-column;
                    .flex-align(flex-start, flex-start);
                    > .message {
                        .flex-none;
                        .width;
                        .flex;
                        .flex-align(flex-start, flex-start);
                        > .system {
                            .width;
                            .flex-center;
                            margin: 0.2em 0;
                            line-height: 1.8em;
                            background: linear-gradient(to right, fade(orangered, 0) 0, orangered 25%, orangered 75%, fade(orangered, 0) 100%);
                            color: white;
                        }
                        > .role {
                            margin: 0.2em;
                            padding: 0.2em;
                            line-height: 1.6em;
                            background-color: skyblue;
                            border-radius: 0.2em;
                        }
                        > .text {
                            margin: 0.2em 0.2em 0.2em 0.5em;
                            line-height: 1.6em;
                            padding: 0.2em;
                            background-color: pink;
                            border-radius: 0.2em;
                            position: relative;
                            .flex-1;
                            .flex;
                            .flex-align(flex-start, flex-start);
                            &:before {
                                content: " ";
                                position: absolute;
                                margin-left: -1.4em;
                                width: 0;
                                height: 0;
                                border: 0.7em solid transparent;
                                border-right: 0.7em solid pink;
                                overflow: hidden;
                            }
                        }
                    }
                }
                > .marquee {
                    padding: 0.2em 0;
                    .flex-1;
                    .flex;
                    .flex-align(flex-start, center);
                    > .message {
                        position: absolute;
                        word-break: keep-all;
                        white-space: nowrap;
                        text-align: left;
                        margin-left: -30em;
                        .flex;
                        .flex-align(flex-start, center);
                        > .system {
                            padding: 0.2em 0.4em;
                            background-color: orangered;
                        }
                        > .role {
                            border-top-left-radius: 0.4em;
                            border-bottom-left-radius: 0.4em;
                            background-color: skyblue;
                            padding: 0.2em 0.4em;
                        }
                        > .text {
                            border-top-right-radius: 0.4em;
                            border-bottom-right-radius: 0.4em;
                            background-color: pink;
                            padding: 0.2em 0.4em;
                        }
                        &.line0 { align-self: flex-start; }
                        &.line1 { align-self: flex-end; }
                        &.line2 { align-self: center; }
                    }
                }
                > .send {
                    height: 3em;
                    .flex-row;
                    > input {
                        border: 1px solid gray;
                        min-width: 5em;
                        .flex-1;
                    }
                    > a {
                        width: 4em;
                        color: white;
                        background-color: blue;
                        .flex-center;
                    }
                }
            }
        }

        .fade-enter-active, .fade-leave-active {
            transition: all .5s;
        }
        .role-move {
            transition: transform .5s;
        }
        .message-enter-active {
            transition: all 5s linear;
        }
        .message-enter {
            margin-left: 100% !important;
        }

        @media screen and (orientation: portrait) {
            .board {
                .column;
                > .palette {
                    height: 4em;
                    border-left: 0;
                    border-right: 0;
                    .width;
                    .row;
                    > .btn {
                        width: 4em;
                        border-left: 1px solid darkgrey;
                        &:first-child {
                            border-left: 0;
                        }
                        & + .expand {
                            border-left: 0;
                        }
                    }
                    > .info {
                        width: 3em;
                        border-left: 1px solid darkgrey;
                    }
                    > .expand {
                        .flex-row;
                        > .fade-enter, > .fade-leave-active {
                            opacity: 0;
                            margin-left: -3em;
                        }
                    }
                }
                > .evaluate {
                    height: 4em;
                    border-left: 0;
                    border-right: 0;
                    .width;
                    .row;
                    > * {
                        width: 4em;
                        border-left: 1px solid darkgrey;
                        &:first-child {
                            border-left: 0;
                        }
                    }
                }
                > .complex {
                    .width;
                    > .messages {
                        .hidden;
                    }
                }
            }
        }

        @media screen and (orientation: landscape) {
            .board {
                .row;
                > .palette {
                    width: 4em;
                    border-top: 0;
                    border-bottom: 0;
                    .height;
                    .column;
                    > .btn {
                        height: 4em;
                        border-top: 1px solid darkgrey;
                        &:first-child {
                            border-top: 0;
                        }
                        & + .expand {
                            border-top: 0;
                        }
                    }
                    > .info {
                        height: 3em;
                        border-top: 1px solid darkgrey;
                    }
                    > .expand {
                        .flex-column;
                        > .fade-enter, > .fade-leave-active {
                            opacity: 0;
                            margin-top: -3em;
                        }
                    }
                }
                > .evaluate {
                    width: 4em;
                    border-top: 0;
                    border-bottom: 0;
                    .height;
                    .column;
                    > * {
                        height: 4em;
                        border-top: 1px solid darkgrey;
                        &:first-child {
                            border-top: 0;
                        }
                    }
                }
                > .complex {
                    .height;
                    > .marquee {
                        .hidden;
                    }
                }
            }
        }
    }
</style>
<script>
    import { mixin, utils } from 'board-game/client';
    import $ from 'jquery'
    import { game } from './../config';

    export default {
        mixins: [ mixin ],
        data() {
            return {
                hold: false,
                timer: false,
                points: [],
                colors: [ 'red', 'yellow', 'green', 'blue', 'white', 'gray', 'black' ],
                brushes: [ 'small', 'medium', 'normal', 'big', 'large' ],
                expand: false,
                message: '',
                lines: 1
            };
        },
        computed: {
            canvas() {
                return this.game && this.game.canvas;
            },
            drawer() {
                return this.board.drawer.player.id === this.player.id;
            },
            drawing() {
                return this.board.status === 'drawing';
            },
            time() {
                if (!this.drawing) {
                    return Math.max(0, game.wait - this.board.time);
                } else {
                    return Math.max(0, game.draw - this.board.time);
                }
            },
            question() {
                if (this.drawer) {
                    if (!this.drawing) {
                        return `下一题:${ this.board.question.answer }`;
                    } else {
                        return `题目:${ this.board.question.answer }`;
                    }
                } else {
                    if (!this.drawing) {
                        return '准备开始';
                    } else {
                        let message = `${ this.board.question.answer.length }个字`;
                        for (let i = 0; i < this.board.question.tips.length; i++) {
                            if (this.board.time > game.tip * (i + 1)) message += `,${ this.board.question.tips[i] }`;
                        }
                        return message;
                    }
                }
            },
            index() {
                let roles = this.game.groups.reduce((s, g) => s.concat(g.roles), []);
                return roles.findIndex(role => this.board.drawer.player.id === role.player.id);
            },
            queue() {
                let roles = this.game.groups.reduce((s, g, i) => s.concat(g.roles.map(role => {
                    role.group = i;
                    return role;
                })), []);
                let index = roles.findIndex(role => this.board.drawer.player.id === role.player.id);
                return roles.slice(index).concat(roles.slice(0, index));
            }
        },
        filters: {
            path(points) {
                return 'M' + points.map(point => point.x + ' ' + point.y).join(' L');
            }
        },
        mounted() {
            setInterval(() => {
                if (this.board) {
                    this.board.time++;
                }
            }, 1000);
            let messages = $("#messages");
            let scrollTimer = 0;
            let scrollToEnd = () => {
                let scrollTop = messages.get(0).scrollHeight - messages.height();
                clearTimeout(scrollTimer);
                if (messages.scrollTop() >= scrollTop) {
                    scrollTimer = setTimeout(scrollToEnd, 40);
                } else {
                    messages.animate({ scrollTop }, 200, () => {
                        setTimeout(scrollToEnd, 40);
                    });
                }
            };
            messages.on('scroll', () => {
                clearTimeout(scrollTimer);
                scrollTimer = setTimeout(scrollToEnd, 2000);
            });
            scrollToEnd();
            $(window).on('resize', () => this.setLines());
            this.setLines();
        },
        methods: {
            setLines() {
                let fontSize = parseFloat($('html').css('font-size'));
                let lineHeight = fontSize * 1.4;
                let height = parseFloat($('#marquee').height());
                if (height >= lineHeight * 3) {
                    this.lines = 3;
                } else if (height >= lineHeight * 2) {
                    this.lines = 2;
                } else {
                    this.lines = 1;
                }
            },
            getPoint(event) {
                return event.targetTouches && event.targetTouches.length ? {
                    x: Math.round(event.targetTouches[0].clientX / utils.vmin * 1000),
                    y: Math.round(event.targetTouches[0].clientY / utils.vmin * 1000)
                } : event.changedTouches && event.changedTouches.length ? {
                    x: Math.round(event.changedTouches[0].clientX / utils.vmin * 1000),
                    y: Math.round(event.changedTouches[0].clientY / utils.vmin * 1000)
                } : {
                    x: Math.round(event.x / utils.vmin * 1000),
                    y: Math.round(event.y / utils.vmin * 1000)
                };
            },
            drawDown(event) {
                if (this.drawer && this.hold === false && this.drawing) {
                    let point = this.getPoint(event);
                    this.$root.emit.drawDown(point);
                    this.hold = [ point ];
                    this.timer = setInterval(() => {
                        if (this.points.length) {
                            this.$root.emit.drawMoves(this.points);
                            this.points = [];
                        }
                    }, 200);
                }
                event.preventDefault();
            },
            drawUp(event) {
                if (this.drawer && this.drawing) {
                    let point = this.getPoint(event);
                    clearInterval(this.timer);
                    if (this.points.length) {
                        this.$root.emit.drawMoves(this.points);
                        this.points = [];
                    }
                    this.$root.emit.drawUp(point);
                    this.hold.push(point);
                    this.hold = false;
                }
                event.preventDefault();
            },
            drawMove(event) {
                if (this.hold && this.drawer && this.drawing) {
                    let point = this.getPoint(event);
                    this.points.push(point);
                    this.hold.push(point);
                }
                event.preventDefault();
            },
            undo() {
                if (this.drawer && this.drawing) {
                    this.$root.emit.undo();
                }
            },
            empty() {
                if (this.drawer && this.drawing) {
                    this.$root.emit.empty();
                }
            },
            setColor(color) {
                if (this.drawer && this.drawing) {
                    this.board.config.color = color;
                    this.$root.emit.setColor(color);
                }
            },
            setSize(size) {
                if (this.drawer && this.drawing) {
                    this.board.config.size = size;
                    this.$root.emit.setSize(size);
                }
            },
            answer() {
                if (this.message) {
                    $(this.$refs.input).blur();
                    this.$root.emit.message(this.message);
                    this.message = '';
                }
            },
            good() {
                if (!this.drawer && !this.role.comment && (this.drawing || this.board.prev)) {
                    this.$root.emit.good();
                }
            },
            bad() {
                if (!this.drawer && !this.role.comment && (this.drawing || this.board.prev)) {
                    this.$root.emit.bad();
                }
            },
            path(points) {
                return 'M' + points.map(point => point.x + ' ' + point.y).join(' L');
            },
            focus(event) {
                $(event.target).focus();
            },
            blur(event) {
                if (event.target !== this.$refs.input) {
                    $(this.$refs.input).blur();
                }
            }
        }
    }
</script>